import redis
import threading
import time
import random

class RedisClient:
    def __init__(self, host='localhost', port=6379, db=0):
        self.redis_client = redis.StrictRedis(host=host, port=port, db=db)
        self.pubsub = self.redis_client.pubsub()

    def send_urls_periodically(self, node_name):
        """定期向redis发送消息 状态上报"""
        while True:
            try:
                url_to_send = self.redis_client.lpop('url_queue')
                if url_to_send:
                    url_to_send = url_to_send.decode('utf-8')
                    self.redis_client.publish(node_name, url_to_send)
                else:
                    print("URL 队列中没有可用的 URL")
            except Exception as e:
                print(f"redis操作出错：{e}")
            time.sleep(10)

    def consume_urls(self, node_name):
        """接收redis消息"""
        self.pubsub.subscribe(node_name)
        for message in self.pubsub.listen():
            if message['type'] == 'message':
                url = message['data'].decode('utf-8')
                yield url

    def add_spider_node(self, node):
        """添加爬虫节点到redis列表中"""
        self.redis_client.rpush('spider_nodes', node)

    def round_robin_dispatch(self, url):
        """轮询分发策略"""
        node = self.redis_client.lpop('spider_nodes')
        if node:
            channel_name = node.decode('utf-8')
            self.redis_client.publish(channel_name, url)
            self.redis_client.rpush('spider_nodes', node)
            return node.decode('utf-8')
        return None

    def random_dispatch(self, url):
        """随机分发策略"""
        nodes = self.redis_client.lrange('spider_nodes', 0, -1)
        if nodes:
            node = random.choice(nodes)
            channel_name = node.decode('utf-8')
            self.redis_client.publish(channel_name, url)
            return node.decode('utf-8')
        return None

    def listen_status_queue(self):
        """订阅信息队列 状态监控"""
        self.pubsub.subscribe('status_queue')
        for message in self.pubsub.listen():
            print(f"Received status: {message['data'].decode('utf-8')}")